package com.jtx.miaoah2.handler;

import com.jtx.miaoah2.Cache.BlankUserCache;
import com.jtx.miaoah2.Common.CustomException;
import com.jtx.miaoah2.Utils.JwtUtils;
import com.jtx.miaoah2.Utils.ThreadLocalUtils;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.util.Strings;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.invoke.MethodHandle;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author 季台星
 * @Date 2023 07 23 14 56
 */
@Slf4j
@Order(0)
public class UserTokenInterceptor extends HandlerInterceptorAdapter {
    /**
     * 需要一个本地缓存记录用户登入
     * 定时任务清除
     */
    public static ConcurrentHashMap<Long, Integer> userRequestCount = new ConcurrentHashMap<>();

    private final BlankUserCache blankUserCache;


    public UserTokenInterceptor(BlankUserCache blankUserCache) {
        this.blankUserCache = blankUserCache;
    }


    //请求拦截前
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if (handler instanceof MethodHandle){
            return true;
        }
        log.info("请求地址为：{}", request.getRequestURI());
        String token = request.getHeader("token");
        if (Strings.isBlank(token)){
            log.info("用户未登入，未得到token");
            throw new CustomException("用户未登入，解析token失败");
        }
        Claims claims = null;
        try {
            claims = JwtUtils.parseJWT(token);
        } catch (Exception e) {
            log.info("用户未登入");
            throw new CustomException("解析token失效，请重新登入");
        }
        if (claims == null){
            log.info("用户未登入");
            return false;
        }
        String subject = claims.getSubject();
        if (null == subject){
            return false;
        }
        //解析出UserId,存入ThreadLocal中
        Long userId = Long.valueOf(subject);
        //校验用户是否在黑名单中
        if (blankUserCache.isExist(userId)) {
            //黑名单内直接拒绝请求
            return false;
        }
        //记录这个用户这段时间内访问次数
        Integer init = userRequestCount.putIfAbsent(userId, 0);
        int count = 0;
        if (init != null){
            count = userRequestCount.get(userId).intValue();
            userRequestCount.put(userId,  count++);
        }
        if (count > 10){
            blankUserCache.addBlankUser(userId);
        }
        ThreadLocalUtils.add(userId);
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        //清理threadLocal中的内容
        ThreadLocalUtils.clear();
    }
}
